<?php

/* ========================================================================= */
/* This file is part of the HypnoPHP Framework Library                       */
/* Copyright (c) 2009-2010, Radu Buzea                                       */
/* ========================================================================= */

/**
* @author Radu Buzea
* @copyright Copyright (c) 2009-2010, Radu Buzea (www.hypnosis.ro)
* @license GNU Lesser General Public License (www.gnu.org/copyleft/lesser.html)
* @package HypnoPHP
* @category Core
* @version 1.0.3
*/

defined('HYPNOPHP_APPLICATION') or
die("Cannot use <i>" . basename(__FILE__) . "</i> outside HypnoPHP Application");

// ============================================================================
// Final class: HSession
// ============================================================================

final class HSession extends HBaseObject
{

	/**
	* Initialize the application session
	*
	* @return void
	* @access public
	* @static
	*/
	public static function initsSession()
	{
		$session = self::getInstance();
		$cache_limiter = HApplication::getConfig('session_cache_limiter');
		if (!empty($cache_limiter) && is_string($cache_limiter)) {
			self::cacheLimiter($cache_limiter);
		}
		$cache_expire = HApplication::getConfig('session_cache_expire');
		if (!empty($cache_expire) && intval($cache_expire) > 0) {
			self::cacheLimiter($cache_expire);
		}
		$session->session_id = session_id();
		$session->session_params = array();
		$session_start = HApplication::getConfig('session_start');
		if (boolval($session_start)) { self::start(); }
	}

	# ###########################################################################

	/**
	* Get and set the current session cache limiter
	*
	* @param string $value One from the list: public, private_no_expire, private, nocache
	* @return string
	*/
	public static function cacheLimiter($value = '')
	{
		$session = self::getInstance();
		if (isset($session->session_id) && $session->session_id != '') {
			$session->addError('Session already started', E_USER_WARNING);
			return;
		}
		if (in_array(trim(strtolower($value)),
			array('public', 'private_no_expire', 'private', 'nocache'))) {
			return session_cache_limiter($cache_limiter);
		}
		return session_cache_limiter();
	}

	# ###########################################################################

	/**
	* Get and set the current session cache expire
	*
	* @param integer $value
	* @return integer
	*/
	public static function cacheExpire($value = 0)
	{
		$session = self::getInstance();
		if (isset($session->session_id) && $session->session_id != '') {
			$session->addError('Session already started', E_USER_WARNING);
			return;
		}
		$value = intval($value);
		if ($value > 0) { return session_cacheExpire($value); }
		return session_cacheExpire();
	}

	# ###########################################################################

	/**
	* Start the application session
	*
	* @return void
	*/
	public static function start()
	{
		$session = self::getInstance();
		$session_started = (isset($session->session_id) && $session->session_id != '');
		if (!$session_started) {
			$session_started = session_start();
			$session->session_id = session_id();
		}
		$session_params = array();
		if ($session_started && count($_SESSION) > 0) {
			foreach ($_SESSION as $param => $value) {
				$session_params[$param] = $value;
			}
		}
		$session->session_params = $session_params;
	}

	# ###########################################################################

	/**
	* Check if a variable is registered in the current session
	*
	* @param string $param The variable name
	* @return boolean
	*/
	public static function registered($param = '')
	{
		$session = self::getInstance();
		$session_params = $session->session_params;
		$param = trim($param);
		if ($param == '') { return false; }
		return isset($session_params[$param]) && !empty($session_params[$param]);
	}

	# ###########################################################################

	/**
	* Unregister a variable from the current session
	*
	* @param string $param The variable name
	* @return bool
	*/
	public static function unregister($param = '')
	{
		$session = self::getInstance();
		$session_params = $session->session_params;
		$param = trim($param);
		if (isset($session_params[$param])) {
			unset($session_params[$param]);
			$session->session_params = $session_params;
			return true;
		}
		return false;
	}

	# ###########################################################################

	/**
	* Register one or more variables with the current session
	*
	* @param mixed $param1 String or array
	* @param mixed $param2
	* @return void
	*/
	public static function register($param1, $param2 = null)
	{
		$session = self::getInstance();
		$params = null;
		if (is_array($param1)) {
			if (is_array($param2)) { $params = array_combine($param1, $param2); }
			else { $params = $param1; }
		} else {
			$params = array($param1 => $param2);
		}
		if (!is_array($params)) { return false; }
		$session_params = $session->session_params;
		foreach ($params as $param => $value) {
			$session_params[$param] = $value;
		}
		$session->session_params = $session_params;
	}

	# ###########################################################################

	/**
	* Return a variable value from the current session
	*
	* @param string $name
	* @return mixed or null if the variable is not registered in the current session
	*/
	public static function getVar($name = '')
	{
		$session = self::getInstance();
		$session_params = $session->session_params;
		$name = trim($name);
		if (!isset($session_params[$name])) { return null; }
		return $session_params[$name];
	}

	# ###########################################################################

	/**
	* Clear all variables from the current session
	*
	* @param mixed $global_session Clear variable form the $_SESSION globals only
	* @return void
	*/
	public static function clear($global_session = false)
	{
		if ($global_session) {
			$_SESSION = array();
		} else {
			$session = self::getInstance();
			$session->session_params = array();
		}
	}

	# ###########################################################################

	/**
	* Save the current session in the $_SESSION globals
	*
	* @return void
	*/
	public static function save_session()
	{
		self::clear(true);
		$session = self::getInstance();
		$session_params = $session->session_params;
		foreach ($session_params as $param => $value) {
			$_SESSION[$param] = $value;
		}
	}

	# ###########################################################################

	/**
	* Get the application session instance (singleton)
	*
	* @return HSession
	*/
	public static function getInstance()
	{
		return self::singleton(__CLASS__);
	}

	# ###########################################################################

}
